package com.diven.common.hive.blood.figure;

import java.util.List;

import javax.swing.JFrame;

import org.jgrapht.Graph;
import org.jgrapht.ext.JGraphXAdapter;
import org.jgrapht.graph.DefaultDirectedGraph;

import com.diven.common.hive.blood.figure.enums.Level;
import com.diven.common.hive.blood.figure.model.ColLine;
import com.diven.common.hive.blood.figure.model.SQLResult;
import com.diven.common.hive.blood.figure.model.TableEdge;
import com.diven.common.hive.blood.figure.model.TableLable;
import com.diven.common.hive.blood.figure.model.TableRelation;
import com.diven.common.hive.blood.figure.model.TableVertex;
import com.mxgraph.layout.mxParallelEdgeLayout;
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout;
import com.mxgraph.swing.mxGraphComponent;

public class HiveSqlBloodFigureGraphFactory {
	
	/**
	 * 	展示血缘图
	 * @param graph
	 */
	public static void show(Graph<TableVertex, TableEdge> graph) {
		JGraphXAdapter<TableVertex, TableEdge> graphx= new JGraphXAdapter<>(graph);
		mxGraphComponent graphComponent = new mxGraphComponent(graphx);
        JFrame frame = new JFrame();
        frame.getContentPane().add(graphComponent);
        new mxHierarchicalLayout(graphx).execute(graphx.getDefaultParent());
        new mxParallelEdgeLayout(graphx).execute(graphx.getDefaultParent());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(800, 600);
		frame.setVisible(true);
	}
	
	/**
	 * 	转换血缘图
	 * @param results 血缘解析结构
	 * @param level	血缘粒度
	 * @return	血缘图
	 */
	public static Graph<TableVertex, TableEdge> toBloodFigureGraph(List<SQLResult> results, Level level) {
		return toBloodFigureGraph(results, level, false);
	}
	
	/**
	 * 	转换血缘图
	 * @param results 血缘解析结构
	 * @param level	血缘粒度
	 * @param speculate 是否开启字段推测
	 * @return	血缘图
	 */
	public static Graph<TableVertex, TableEdge> toBloodFigureGraph(List<SQLResult> results, Level level, boolean speculate) {
		Graph<TableVertex, TableEdge> graph = new DefaultDirectedGraph<TableVertex, TableEdge>(TableEdge.class);
		//添加节点
		for(SQLResult item : results){
			for(String table : item.getInputTables()) {
				graph.addVertex(new TableVertex(TableLable.LABLE_TABLE, table));
			}
			for(String table : item.getOutputTables()) {
				graph.addVertex(new TableVertex(TableLable.LABLE_TABLE, table));
			}
			if(Level.FILELD == level) {
				for(ColLine colLine :item.getColLineList()){
					//字段-源信息表
					for(String from : colLine.getFromNameSet()) {
						if(from.contains("&")) {
							//处理不明确的推断
							if(speculate) {
								//这里需要元数据信息的支持
							}
							String field = from.substring(from.lastIndexOf(".")+1);
							for(String table : from.substring(0, from.lastIndexOf(".")).split("&")) {
								graph.addVertex(new TableVertex(TableLable.LABLE_FIELD, table+"."+field));
							}
						}
						else {
							graph.addVertex(new TableVertex(TableLable.LABLE_FIELD, from));
						}
					}
					//字段-目标表
					graph.addVertex(new TableVertex(TableLable.LABLE_FIELD, colLine.getToTableFieldParse(speculate)));
				}
				
			}
		}
		
		//添加关系
		for(SQLResult item : results){
			//表依赖
			for(String start : item.getInputTables()) {
				for(String end : item.getOutputTables()) {
					graph.addEdge(new TableVertex(TableLable.LABLE_TABLE, start), new TableVertex(TableLable.LABLE_TABLE, end), new TableEdge(TableRelation.REL_TABLE_TO_TABLE));
				}
			}
			//字段依赖
			if(Level.FILELD == level) {
				for(ColLine colLine :item.getColLineList()){
					//字段-属性-源信息表
					for(String from : colLine.getFromNameSet()) {
						if(from.contains("&")) {
							//处理不明确的推断
							String field = from.substring(from.lastIndexOf(".")+1);
							for(String table : from.substring(0, from.lastIndexOf(".")).split("&")) {
								graph.addEdge(new TableVertex(TableLable.LABLE_FIELD, table+"."+field), new TableVertex(TableLable.LABLE_TABLE, table), new TableEdge(TableRelation.REL_TABLE_TO_FIELD));
							}
						}
						else {
							graph.addEdge(new TableVertex(TableLable.LABLE_FIELD, from), new TableVertex(TableLable.LABLE_TABLE, from.substring(0, from.lastIndexOf("."))), new TableEdge(TableRelation.REL_TABLE_TO_FIELD));
						}
					}
					//字段-属性-目标表
					graph.addEdge(new TableVertex(TableLable.LABLE_FIELD, colLine.getToTableFieldParse(speculate)), new TableVertex(TableLable.LABLE_TABLE, colLine.getToTable()), new TableEdge(TableRelation.REL_TABLE_TO_FIELD));
					//构建字段间的关联关系
					for(String from : colLine.getFromNameSet()) {
						if(from.contains("&")) {
							//处理不明确的推断
							String field = from.substring(from.lastIndexOf(".")+1);
							for(String table : from.substring(0, from.lastIndexOf(".")).split("&")) {
								graph.addEdge(new TableVertex(TableLable.LABLE_FIELD, table+"."+field), new TableVertex(TableLable.LABLE_TABLE,table), new TableEdge(TableRelation.REL_TABLE_TO_FIELD));
								graph.addEdge(new TableVertex(TableLable.LABLE_FIELD, table+"."+field), new TableVertex(TableLable.LABLE_FIELD, colLine.getToTableFieldParse(speculate)), new TableEdge(TableRelation.REL_FIELD_TO_FIELD));
							}
						}
						else {
							graph.addEdge(new TableVertex(TableLable.LABLE_FIELD, from), new TableVertex(TableLable.LABLE_FIELD, colLine.getToTableFieldParse(speculate)), new TableEdge(TableRelation.REL_FIELD_TO_FIELD));
						}
					}
				}
			}
		}
		return graph;
	}
	
}
